﻿
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Interactivity;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Phone.Framework.Threads;

namespace Phone.Framework.Behaviors
{

    /// <summary>
    /// Custom behavior that updates the source of a binding on a text box as the text changes.
    /// </summary>
    public class UpdateTextBindingOnPropertyChanged : Behavior<TextBox>
    {
        private BindingExpression expression;


        /// <summary>
        /// Called after the behavior is attached to an AssociatedObject.
        /// </summary>
        /// <remarks>
        /// Override this to hook up functionality to the AssociatedObject.
        /// </remarks>
        protected override void OnAttached()
        {
            base.OnAttached();

            this.expression = this.AssociatedObject.GetBindingExpression(TextBox.TextProperty);
            
            this.AssociatedObject.TextChanged += this.OnTextChanged;
        }

        /// <summary>
        /// Called when the behavior is being detached from its AssociatedObject, but before it has actually occurred.
        /// </summary>
        /// <remarks>
        /// Override this to unhook functionality from the AssociatedObject.
        /// </remarks>
        protected override void OnDetaching()
        {
            base.OnDetaching();
            
            this.AssociatedObject.TextChanged -= this.OnTextChanged;
            this.expression = null;
        }

        private void OnTextChanged(object sender, EventArgs args)
        {
            if (!string.IsNullOrEmpty(AssociatedObject.Text))
            {
                AssociatedObject.Focus();
                AssociatedObject.SelectionStart = AssociatedObject.Text.Length;
            }
            this.expression.UpdateSource();
        }
    }

    public class UpdateSelectedValueOnPropertyChanged : Behavior<TextBox>
    {
        private DelayTimer _delayTimer = new DelayTimer();


        /// <summary>
        /// Called after the behavior is attached to an AssociatedObject.
        /// </summary>
        /// <remarks>
        /// Override this to hook up functionality to the AssociatedObject.
        /// </remarks>
        protected override void OnAttached()
        {
            base.OnAttached();

            _delayTimer.InitInvoke(0.65, InternalSearch);
            this.AssociatedObject.TextChanged += this.OnTextChanged;
        }

        public void InternalSearch(object key)
        {
            if (Selector != null && !string.IsNullOrEmpty(SelectedValue))
            {
                Selector.SelectedValue = AssociatedObject.Text;
            }
           // SelectedValue = string.Empty;
            //UIThread.Invoke(() =>
            //{
            //    if (Selector != null)
            //        Selector.SelectedValue = AssociatedObject.Text;
            //});
        }

        /// <summary>
        /// Called when the behavior is being detached from its AssociatedObject, but before it has actually occurred.
        /// </summary>
        /// <remarks>
        /// Override this to unhook functionality from the AssociatedObject.
        /// </remarks>
        protected override void OnDetaching()
        {
            base.OnDetaching();

            this.AssociatedObject.TextChanged -= this.OnTextChanged;
           
        }

        private void OnTextChanged(object sender, EventArgs args)
        {
            if (!string.IsNullOrEmpty(AssociatedObject.Text))
            {
                _delayTimer.AddObj(AssociatedObject.Text);
            }
        }

        public ListBox Selector
        {
            get { return (ListBox)GetValue(SelectorProperty); }
            set { SetValue(SelectorProperty, value); }
        }

       
        public static readonly DependencyProperty SelectorProperty =
            DependencyProperty.Register("Selector", typeof(ListBox), typeof(UpdateSelectedValueOnPropertyChanged), 
            new PropertyMetadata(null));


        public string SelectedValue
        {
            get { return (string)GetValue(SelectedValueProperty); }
            set { SetValue(SelectedValueProperty, value); }
        }

        // Using a DependencyProperty as the backing store for SelectedValue.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty SelectedValueProperty =
            DependencyProperty.Register("SelectedValue", typeof(string), typeof(UpdateSelectedValueOnPropertyChanged),
            new PropertyMetadata((s, a) => {
                var behavior = s as UpdateSelectedValueOnPropertyChanged;
                behavior.InternalSearch(null);
            }));
    }
}
